package com.poi.exp.analysis;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.poi.common.CoreConstants;
import com.poi.exception.PoiElErrorCode;
import com.poi.exp.domain.BaseModel;
import com.poi.exp.domain.CellModelVO;
import com.poi.exp.domain.LoopRowModelVO;
import com.poi.exp.domain.RowModelVO;
import com.poi.util.PoiContextUtil;

/**
 * <poi:foreach></poi:foreach>的处理器
 * 
 * @author wzy
 *
 */
public class LoopRowAnalysis implements RowAnalysis {
	private static final Logger log = LoggerFactory.getLogger(LoopRowAnalysis.class);

	@Override
	public RowModelVO dealRow(Row topRow) {
		Cell beginCell = topRow.getCell(support(topRow));

		// 从beginCell中找出list key
		String beginCellContent = beginCell.getStringCellValue();
		Matcher ma = Pattern.compile(CoreConstants.POI_FOREACH_START_REGEX).matcher(beginCellContent);
		String key = null;
		if (ma.find()) {
			key = ma.group(1).trim();
		} else {
			throw PoiElErrorCode.TAG_NOT_FOUND.exp(beginCellContent, CoreConstants.POI_FOREACH_START_REGEX);
		}
		// 当前行，后面有用
		int currentRowIndex = topRow.getRowNum();
		LoopRowModelVO tpRow = new LoopRowModelVO();
		tpRow.setKeyeExpression(key);

		// 本循环内存储的单元格信息
		List<BaseModel> cellList = new ArrayList<>();
		tpRow.setCellList(cellList);
//		
//		// 循环嵌套循环
//		List<LoopRowModelVO> loopList = new ArrayList<>();
//		tpRow.setLoopList(loopList);

		int beginRowNum = beginCell.getRow().getRowNum();
		Pattern prePattern = Pattern.compile(CoreConstants.POI_FOREACH_START_REGEX);
		Pattern postPattern = Pattern.compile(CoreConstants.POI_FOREACH_END_REGEX);
		int k = PoiContextUtil.getContext().getAnalysisColumn();
		while (beginRowNum <= beginCell.getSheet().getLastRowNum() && null == tpRow.getLineEndIndex()) {
			Row currentRow = beginCell.getSheet().getRow(beginRowNum);
			PoiContextUtil.getContext().setAnalysisRowNum(currentRow.getRowNum());
			if (currentRow == null) {
				// throw new Exception();
			}
			if(currentRowIndex !=beginRowNum ) {
				k=0;
			}
			//行数是否+1
			boolean beginRowNumAdd=true;
			for ( int end = currentRow.getLastCellNum();
					k <= end; k++) {
				Cell cell = currentRow.getCell(k);
				//记录解析到哪里列，有循环嵌套时就能不在解析本列
				PoiContextUtil.getContext().setAnalysisColumn(k);
				if (null == cell) {
					continue;
				}
				CellModelVO cellVO = new CellModelVO();
				cellVO.setCell(cell);
				// 加入集合
				cellList.add(cellVO);
				String expressionStr = cell.getRichStringCellValue().getString().trim();
				if (expressionStr.equals("")) {
					continue;
				}
				String value = expressionStr;
				cellVO.setExpression(value);

				Matcher preMatcher = prePattern.matcher(value);
				if (preMatcher.find()) {
					// value = preMatcher.replaceAll("");
					// 此处的逻辑是 for循环必须是一行，以前写过 解析到cell一行内允许两个for循环
					if (null == tpRow.getLineBeginIndex() && null == tpRow.getLineEndIndex()) {
						tpRow.setLineBeginIndex(currentRow.getRowNum());
						tpRow.setColumnBeginIndex(k);
						//去除循环标签
						cellVO.setExpression("");
					} else {
						//行数能+1，有下面决定
						beginRowNumAdd=false;
						
						cellList.remove(cellVO);
						
						//tpRow.setLineBeginIndex(currentRow.getRowNum());
						tpRow.setColumnBeginIndex(k);
						
						LoopRowModelVO nextRowModel = (LoopRowModelVO) dealRow(currentRow);
						cellList.add(nextRowModel);
						//在同一行内 for嵌套
						if(beginRowNum!=PoiContextUtil.getContext().getAnalysisRowNum()) {
							tpRow.setLineNum(tpRow.getLineNum() + nextRowModel.getLineNum());
							beginRowNum+=nextRowModel.getLineNum();
						}
						break;
						
					}
					
				}
				Matcher postMatcher = postPattern.matcher(value);
				if (postMatcher.find()) {

					tpRow.setLineEndIndex(currentRow.getRowNum());
					tpRow.setColumnEndIndex(k);
					//去除循环标签
					cellVO.setExpression("");
					//记录解析列标签
					PoiContextUtil.getContext().setAnalysisColumn(k+1);
				}
				// 存放<单元格列号, 单元格内容>。单元格内容是除去tag之外的
				// map.put(k, value);
			}
			if(beginRowNumAdd) {
				beginRowNum++;
			}
			
		}
		// tpRow.setCellMap(cellMap);

//		Object rootObject = peContext.getRootObjectMap().get(key);
//		if (!(rootObject instanceof List)) {
//			throw PoiElErrorCode.ILLEGAL_PARAM.exp("<poi:foreach>中list：" + key + "对应的值应该为List");
//		}

//		List<?> ls = (List<?>) rootObject;

		// transfer
//		setMutiData(beginCell, ls, tpRow, peContext);

//		return ls.size() * (tpRow.getEnd() - tpRow.getBegin() + 1);
		PoiContextUtil.getContext().setWriterRowNum(topRow.getRowNum()+tpRow.getLineNum());
		return tpRow;
	}

//	/**
//	 * 进行拷贝和赋值
//	 * 
//	 * @param cell
//	 * @param ls
//	 * @param tpRow
//	 * @param parser
//	 */
//	private static void setMutiData(Cell cell, List<?> ls, MutiRowModel tpRow, PoiExporterContext peContext) {
//		XSSFSheet sheet = cell.getSheet();
//		int mutiRow = tpRow.getEnd() - tpRow.getBegin() + 1; // 循环的行数
//		// 行往下移
//		if (ls.size() > 1) { // fix 只有一条数据时，不需要下移
//			sheet.shiftRows(tpRow.getEnd() + 1, sheet.getLastRowNum() + 3, (ls.size() - 1) * mutiRow, true, false);
//		}
//
//		Map<Integer, Map<Integer, Object>> cellMap = tpRow.getCellMap();
//
//		for (int i = 0; i < ls.size(); i++) {
//			Object rootObjectItem = ls.get(i);
//			for (Integer key1 : cellMap.keySet()) { // key1为row行号
//				Row curRow = null;
//				if (i == 0) {
//					curRow = sheet.getRow(key1);
//				} else {
//					curRow = sheet.createRow(i * mutiRow + key1);
//					// 拷贝样式
//					copyCellStyle(sheet.getRow(key1), curRow);
//					// 合并 这里合并单元格是因为使用 shiftRows 移动行之后，所有的合并样式都丢失了
//					copyMergeRegion(sheet, key1, i * mutiRow + key1);
//				}
//
//				// 处理当前行里面的每个单元格：替换内容
//				Map<Integer, Object> map = cellMap.get(key1);
//				for (Integer key : map.keySet()) {
//					String cellContent = map.get(key) == null ? "" : (String) map.get(key);
//					Cell c = curRow.getCell(key);
//					c.setCellValue(parseValue(cellContent, rootObjectItem, peContext));
//				}
//			}
//		}
//
//	}

//	/**
//	 * 拷贝样式
//	 * 
//	 * @param src
//	 * @param des
//	 */
//	private static void copyCellStyle(Row src, Row des) {
//		for (int i = src.getFirstCellNum(); i < src.getLastCellNum(); i++) {
//			if (null != src.getCell(i)) {
//				logger.info("StringCellValue={}", src.getCell(i).getStringCellValue());
//				des.createCell(i).setCellStyle(src.getCell(i).getCellStyle());
//			}
//
//		}
//	}

	/**
	 * 拷贝合并单元格
	 * 
	 * @param sheet
	 * @param srcRow
	 * @param desRow
	 */
	private static void copyMergeRegion(XSSFSheet sheet, int srcRow, int desRow) {
		for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
			CellRangeAddress oldRegion = sheet.getMergedRegion(j);
			if ((oldRegion.getFirstRow() == srcRow) && (oldRegion.getLastRow() == srcRow)) {
				int oldFirstCol = oldRegion.getFirstColumn();
				int oldLastCol = oldRegion.getLastColumn();
				CellRangeAddress newRegion = new CellRangeAddress(desRow, desRow, oldFirstCol, oldLastCol);
				// System.out.println(desRow+","+desRow+","+oldFirstCol+","+oldLastCol);
				sheet.addMergedRegion(newRegion);
			}
		}
	}

	@Override
	public int support(Row row) {
		for (int k = 0; k <= row.getLastCellNum(); k++) {
			Cell cell = row.getCell(k);
			if (null != cell && cell.getCellType() == Cell.CELL_TYPE_STRING) {
				String content = cell.getStringCellValue().trim();
				Pattern prePattern = Pattern.compile(CoreConstants.POI_FOREACH_START_REGEX);
				Matcher matcher = prePattern.matcher(content);
				if (matcher.find()) {
					return k;
				}
			}
		}
		return -1;
	}

	public static void main(String[] args) {
		String content = "<poi:foreach list=\"list\"> #{index}";
//		String content = "<poi:foreach list=\"list\">";
		boolean flag = content.matches("<poi:foreach\\s+list=\"(\\w+)\">");
		System.out.println(flag);

		Pattern prePattern = Pattern.compile(CoreConstants.POI_FOREACH_START_REGEX);
		Matcher matcher = prePattern.matcher(content);
		boolean f = matcher.find();
		System.out.println(f);
		System.out.println(matcher.replaceAll(""));
	}

}
